// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported ScreenshotService, ScreenshotUI, showScreenshotUI */
-const { Clutter, Gio, GObject, GLib, Gtk, Meta, Shell, St } = imports.gi;
+const { Clutter, Cogl, Gio, GObject, GLib, Gtk, Meta, Shell, St } = imports.gi;
const GrabHelper = imports.ui.grabHelper;
const Layout = imports.ui.layout;
this.close();
}
- _storeScreenshot(bytes) {
+ _storeScreenshot(bytes, pixbuf) {
// Store to the clipboard first in case storing to file fails.
const clipboard = St.Clipboard.get_default();
clipboard.set_content(St.ClipboardType.CLIPBOARD, 'image/png', bytes);
// Add it to recent files.
Gtk.RecentManager.get_default().add_item(file.get_uri());
+ // Create a St.ImageContent icon for the notification. We want
+ // St.ImageContent specifically because it preserves the aspect ratio when
+ // shown in a notification.
+ const pixels = pixbuf.read_pixel_bytes();
+ const content =
+ St.ImageContent.new_with_preferred_size(pixbuf.width, pixbuf.height);
+ content.set_bytes(
+ pixels,
+ Cogl.PixelFormat.RGBA_8888,
+ pixbuf.width,
+ pixbuf.height,
+ pixbuf.rowstride
+ );
+
// Show a notification.
const source = new MessageTray.Source(
// Translators: notification source name.
_('Screenshot captured'),
// Translators: notification body when a screenshot was captured.
_('You can paste the image from the clipboard.'),
- {
- datetime: time,
- gicon: Gio.BytesIcon.new(bytes),
- }
+ { datetime: time, gicon: content }
);
// Translators: button on the screenshot notification.
notification.addAction(_('Show in Files'), () => {
this._cursor.y * this._scale,
this._cursorScale,
stream
- ).then(() => {
+ ).then(pixbuf => {
stream.close(null);
- this._storeScreenshot(stream.steal_as_bytes());
+ this._storeScreenshot(stream.steal_as_bytes(), pixbuf);
}).catch(err => {
logError(err, 'Error capturing screenshot');
});
window.cursorPoint.y * window.bufferScale,
this._cursorScale,
stream
- ).then(() => {
+ ).then(pixbuf => {
stream.close(null);
- this._storeScreenshot(stream.steal_as_bytes());
+ this._storeScreenshot(stream.steal_as_bytes(), pixbuf);
}).catch(err => {
logError(err, 'Error capturing screenshot');
});
#undef INDEX_B
static void
-composite_to_stream_on_png_saved (GObject *source,
+composite_to_stream_on_png_saved (GObject *pixbuf,
GAsyncResult *result,
gpointer user_data)
{
if (!gdk_pixbuf_save_to_stream_finish (result, &error))
g_task_return_error (task, error);
else
- g_task_return_boolean (task, TRUE);
+ g_task_return_pointer (task, g_object_ref (pixbuf), g_object_unref);
g_object_unref (task);
}
* Finish the asynchronous operation started by
* shell_screenshot_composite_to_stream () and obtain its result.
*
- * Returns: whether the operation was successful
+ * Returns: (transfer full) (nullable): a GdkPixbuf with the final image if the
+ * operation was successful, or NULL on error.
*
*/
-gboolean
+GdkPixbuf *
shell_screenshot_composite_to_stream_finish (GAsyncResult *result,
GError **error)
{
shell_screenshot_composite_to_stream),
FALSE);
- return g_task_propagate_boolean (G_TASK (result), error);
+ return g_task_propagate_pointer (G_TASK (result), error);
}
ShellScreenshot *